package fileConfig;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map.Entry;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.NumberToTextConverter;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class readExcel {
	 private static final String XLS = "xls";
	 private static final String XLSX = "xlsx";
	 

	public static void main(String[] args) {
//		readExcel re=new readExcel();
//		HashMap<String,sheetData> excelData=re.readExcel("resource/webHomePageTest.xlsx");
//		re.systemOutExcesData(excelData);
	}
	
	public void systemOutExcesData(HashMap<String,sheetData> excelData) {
		for (Entry<String, sheetData> entry : excelData.entrySet()) {
			System.out.println("sheetName="+entry.getKey()+"  data:");
			for (HashMap<String, Object> data : entry.getValue().getSheetData()) {
				for (Entry<String, Object> rowdata :data.entrySet()) {
					System.out.print(rowdata.getKey()+"="+rowdata.getValue()+"   ");
				}
				System.out.println();
			}
		}
	}
	
    /**
     * 根据文件后缀名类型获取对应的工作簿对象
     * @param inputStream 读取文件的输入流
     * @param fileType 文件后缀名类型（xls或xlsx）
     * @return 包含文件数据的工作簿对象
     * @throws IOException
     */
	public  Workbook getWorkbook(InputStream inputStream, String fileType) {
		Workbook workbook = null;
		try {
			if (fileType.equalsIgnoreCase(XLS)) {
				workbook = new HSSFWorkbook(inputStream);

			} else if (fileType.equalsIgnoreCase(XLSX)) {
				workbook = new XSSFWorkbook(inputStream);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return workbook;
	}
	
	/**
	 * 判断是否是日期，若是返回日期字符串，否则返回数字字符串
	 *
	 * @param value
	 * @param formatIndex
	 * @param formatString
	 * @return
	 */
	public String formatRawCellContents(double value, int formatIndex, String formatString) {
	    // Is it a date?
	    if (DateUtil.isADateFormat(formatIndex, formatString)) {
	        if (DateUtil.isValidExcelDate(value)) {

	            Date d = DateUtil.getJavaDate(value);
	            SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
	            return f.format(d);
	        }
	    }
	    String _value = NumberToTextConverter.toText(value);
	    if (_value.indexOf('E') > -1) {
	        //若是科学计数法,则转换为非科学计数法
	        return new BigDecimal(value).toString();
	    }
	    return _value;
	}

	/**
	 * 转换数据类型
	 * @param cellValue
	 * @param fieldType
	 * @return
	 */
	public Object convertToFieldType(Object cellValue, Class<?> fieldType) {
		  String value = String.valueOf(cellValue);
		  if (fieldType == Double.class || fieldType == double.class) {
		    return Double.valueOf(value);
		  }
		  if (fieldType == Integer.class || fieldType == int.class) {
		    return Double.valueOf(value).intValue();
		  }
		  if (fieldType == Short.class || fieldType == short.class) {
		    return Double.valueOf(value).shortValue();
		  }
		  if (fieldType == Long.class || fieldType == long.class) {
		    return Double.valueOf(value).longValue();
		  }
		  if (fieldType == Float.class || fieldType == float.class) {
		    return Double.valueOf(value).floatValue();
		  }
		  if (fieldType == Character.class || fieldType == char.class) {
		    return value.charAt(0);
		  }
		  if (fieldType == Date.class) {
		    return DateUtil.getJavaDate(Double.valueOf(value));
		  }
		  return value;
		}
	
	/**
     * 将单元格内容转换为字符串
     * @param cell
     * @return
     */
	public  String convertCellValueToString(Cell cell) {
        if(cell==null){
            return null;
        }
        String returnValue = null;
        switch (cell.getCellType()) {
            case NUMERIC:   //数字
                Double doubleValue = cell.getNumericCellValue();
                // 格式化科学计数法，取2位整数
                DecimalFormat df = new DecimalFormat("00");
                returnValue = df.format(doubleValue);
                break;
            case STRING:    //字符串
                returnValue = cell.getStringCellValue();
                break;
            case BOOLEAN:   //布尔
                Boolean booleanValue = cell.getBooleanCellValue();
                returnValue = booleanValue.toString();
                break;
            case BLANK:     // 空值
            	return null;
            case FORMULA:   // 公式
                 doubleValue = cell.getNumericCellValue();
                df = new DecimalFormat("0");
                returnValue = df.format(doubleValue);
                //returnValue = cell.getCellFormula();
                break;
            case ERROR:     // 故障
            	break;
            default:
                break;
        }
        return returnValue;
    }

    /**
     * 读取Excel文件内容
     * @param fileName 要读取的Excel文件所在路径
     * @return 读取结果列表，读取失败时返回null
     */
    public HashMap<String,sheetData> readExcel(String fileName) {
        Workbook workbook = null;
        FileInputStream inputStream = null;

        try {
            // 获取Excel后缀名
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            // 获取Excel文件
            File excelFile = new File(fileName);
            if (!excelFile.exists()) {
                System.out.println("指定的Excel文件不存在！");
                return null;
            }

            // 获取Excel工作簿
            inputStream = new FileInputStream(excelFile);
            workbook = getWorkbook(inputStream, fileType);

            // 读取excel中的数据
            HashMap<String,sheetData> resultDataList = parseExcel(workbook);
            return resultDataList;
        } catch (Exception e) {
        	System.out.println("解析Excel失败，文件名：" + fileName + " 错误信息：" + e.getMessage());
            return null;
        } finally {
            try {
                if (null != workbook) {
                    workbook.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (Exception e) {
            	System.out.println("关闭数据流出错！错误信息：" + e.getMessage());
                return null;
            }
        }
    }
    
    /**
     * 解析Excel数据
     * @param workbook Excel工作簿对象
     * @return 解析结果
     * @throws IOException 
     */
    public HashMap<String,sheetData> parseExcel(Workbook workbook){
    	HashMap<String,sheetData> resultDataList = new HashMap<String,sheetData>();    
        // 解析sheet
    	sheetData sd=null;
        for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
            Sheet sheet = workbook.getSheetAt(sheetNum);
            String sheetName=sheet.getSheetName();
            //System.out.println(sheetName);                       

            // 校验sheet是否合法
            if (sheet == null) {
                continue;
            }

            // 获取第一行表头
            int firstRowNum = sheet.getFirstRowNum();
            Row firstRow = sheet.getRow(firstRowNum);
            if (null == firstRow) {
                System.out.println(sheetName+"=解析Excel失败，在第一行没有读取到任何数据！");
                continue;
            }
            
            ArrayList<String> sheetHeader=new ArrayList<String> ();
            ArrayList<HashMap<String,Object>> sheetDatas=new ArrayList<HashMap<String,Object>> ();
            for(int i=0;i<firstRow.getLastCellNum();i++){
            	sheetHeader.add(firstRow.getCell(i)+"");
            }

            // 解析每一行的数据，构造数据对象
            int rowStart = firstRowNum + 1;
            int rowEnd = sheet.getPhysicalNumberOfRows();
            for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
                Row row = sheet.getRow(rowNum); 
                HashMap<String,Object> rowData=new HashMap<String,Object>();
                for(int i=0;i<row.getLastCellNum();i++){
                	rowData.put(sheetHeader.get(i),convertCellValueToString(row.getCell(i)) );
                	//System.out.println(sheetHeader.get(i)+"="+convertCellValueToString(row.getCell(i)));
                }
                sheetDatas.add(rowData);
                if (null == row) {
                	System.out.println("第 " + row.getRowNum() + "行数据不合法，已忽略！");
                    continue;
                }
                sd=new sheetData(sheetName,sheetHeader,sheetDatas);
            }
            if(sd!=null)resultDataList.put(sheetName, sd);
        }
        return resultDataList;
    }    
}

